package com.mspbots.rule.queue.timeentry;

import com.mspbots.api.client.WiseClient;
import com.mspbots.cw.request.TenantTimeEntryDTO;
import com.mspbots.cw.request.TenantUserDTO;
import com.mspbots.rule.exceptions.BaseRule;
import com.mspbots.rule.exceptions.cw.CwBaseRule;
import com.mspbots.rule.queue.BaseQueue;
import lombok.extern.slf4j.Slf4j;
import org.jeasy.rules.api.Facts;
import org.jeasy.rules.api.Rules;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

import static java.time.temporal.ChronoUnit.SECONDS;

/**
 * @ClassName com.mspbots.rule.queue.timeentry.BaseTrigger
 * @Description TODO
 * @Author Jun
 * @Date 2019/8/30 18:38
 * @Version 1.0
 **/
@Slf4j
@Component
public class TimeEntryBaseQueue extends BaseQueue {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private WiseClient wiseClient;

    @Async
    protected void onRule(String ruleName, TenantTimeEntryDTO tenantUserTimeEntry) {
        try {
            CwBaseRule instance = getInstance(ruleName, tenantUserTimeEntry);
            if (instance != null) {
                fire(instance, tenantUserTimeEntry);
            }
        } catch (Exception e) {
            log.error("trigger [{}] fire error : {}", ruleName, e.getMessage());
            e.printStackTrace();
        }
    }

    protected CwBaseRule getInstance(String ruleName, TenantTimeEntryDTO tenantUserTimeEntry) {
        try {
            if (checkRule(ruleName, tenantUserTimeEntry.getTenantId())) {
                log.debug("time entry rule [{}] [{}] ", tenantRuleDTO.getRuleId(), tenantUserTimeEntry.getCwTid());
                Map<String, Object> params = new HashMap<>();
                params.put("tenantId", tenantUserTimeEntry.getTenantId());
                params.put("cwUid", tenantUserTimeEntry.getCwUid());
                TenantUserDTO tenantUserDTO = coreClient.get("/" + tenantUserTimeEntry.getTenantId() + "/user/info", params, TenantUserDTO.class).block(Duration.of(5, SECONDS));
                if (tenantUserDTO == null) {
                    return null;
                } else {
                    tenantUserTimeEntry.setTenantUserId(tenantUserDTO.getId());
                }
                Class clazz = Class.forName(tenantRuleDTO.getClassName());
                CwBaseRule instance = (CwBaseRule) clazz.getDeclaredConstructor().newInstance();
                instance.init(tenantRuleDTO, messageProducer, messagesService, tenantUserMappingService,
                        tenantConfigurationService, coreClient, objectMapper);
                instance.setStringRedisTemplate(stringRedisTemplate);
                instance.setWiseClient(wiseClient);
                return instance;
            }
        } catch (Exception e) {
            log.error("trigger [{}] fire error : {} : {}", ruleName, e.getMessage(), tenantUserTimeEntry);
            e.printStackTrace();
        }
        return null;
    }

    protected void fire(CwBaseRule instance, TenantTimeEntryDTO tenantUserTimeEntry) {
        Rules rules = new Rules();
        rules.register(instance);
        Facts facts = new Facts();
        facts.put(BaseRule.FACT, tenantUserTimeEntry);
        rulesEngine.fire(rules, facts);
    }
}
